home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / msdos / fronthlp.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  37KB  |  1,363 lines

  1. #include "driver.h"
  2. #include "info.h"
  3. #include "audit.h"
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <dos.h>
  8. #include <sys/stat.h>
  9. #include <sys/errno.h>
  10. #include <dirent.h>
  11. #include <unzip.h>
  12.  
  13. #ifdef MESS
  14. #include "mess/msdos.h"
  15. #endif
  16.  
  17. int silentident,knownstatus;
  18.  
  19. #define KNOWN_START 0
  20. #define KNOWN_ALL   1
  21. #define KNOWN_NONE  2
  22. #define KNOWN_SOME  3
  23.  
  24. extern unsigned int crc32 (unsigned int crc, const unsigned char *buf, unsigned int len);
  25.  
  26.  
  27. void get_rom_sample_path (int argc, char **argv, int game_index);
  28.  
  29. static const struct GameDriver *gamedrv;
  30.  
  31. /* compare string[8] using standard(?) DOS wildchars ('?' & '*')      */
  32. /* for this to work correctly, the shells internal wildcard expansion */
  33. /* mechanism has to be disabled. Look into msdos.c */
  34.  
  35. int strwildcmp(const char *sp1, const char *sp2)
  36. {
  37.     char s1[9], s2[9];
  38.     int i, l1, l2;
  39.     char *p;
  40.  
  41.     strncpy(s1, sp1, 8); s1[8] = 0; if (s1[0] == 0) strcpy(s1, "*");
  42.  
  43.     strncpy(s2, sp2, 8); s2[8] = 0; if (s2[0] == 0) strcpy(s2, "*");
  44.  
  45.     p = strchr(s1, '*');
  46.     if (p)
  47.     {
  48.         for (i = p - s1; i < 8; i++) s1[i] = '?';
  49.         s1[8] = 0;
  50.     }
  51.  
  52.     p = strchr(s2, '*');
  53.     if (p)
  54.     {
  55.         for (i = p - s2; i < 8; i++) s2[i] = '?';
  56.         s2[8] = 0;
  57.     }
  58.  
  59.     l1 = strlen(s1);
  60.     if (l1 < 8)
  61.     {
  62.         for (i = l1 + 1; i < 8; i++) s1[i] = ' ';
  63.         s1[8] = 0;
  64.     }
  65.  
  66.     l2 = strlen(s2);
  67.     if (l2 < 8)
  68.     {
  69.         for (i = l2 + 1; i < 8; i++) s2[i] = ' ';
  70.         s2[8] = 0;
  71.     }
  72.  
  73.     for (i = 0; i < 8; i++)
  74.     {
  75.         if (s1[i] == '?' && s2[i] != '?') s1[i] = s2[i];
  76.         if (s2[i] == '?' && s1[i] != '?') s2[i] = s1[i];
  77.     }
  78.  
  79.     return stricmp(s1, s2);
  80. }
  81.  
  82.  
  83. /* Identifies a rom from from this checksum */
  84. void identify_rom(const char* name, int checksum, int length)
  85. {
  86. /* Nicola output format */
  87. #if 1
  88.     int found = 0;
  89.  
  90.     /* remove directory name */
  91.     int i;
  92.     for (i = strlen(name)-1;i >= 0;i--)
  93.     {
  94.         if (name[i] == '/' || name[i] == '\\')
  95.         {
  96.             i++;
  97.             break;
  98.         }
  99.     }
  100.     if (!silentident)
  101.         printf("%-12s ",&name[i]);
  102.  
  103.     for (i = 0; drivers[i]; i++)
  104.     {
  105.         const struct RomModule *romp;
  106.  
  107.         romp = drivers[i]->rom;
  108.  
  109.         while (romp && (romp->name || romp->offset || romp->length))
  110.         {
  111.             if (romp->name && romp->name != (char *)-1 && checksum == romp->crc)
  112.             {
  113.                 if (!silentident)
  114.                 {
  115.                     if (found != 0)
  116.                         printf("             ");
  117.                     printf("= %-12s  %s\n",romp->name,drivers[i]->description);
  118.                 }
  119.                 found++;
  120.             }
  121.             romp++;
  122.         }
  123.     }
  124.     if (found == 0)
  125.     {
  126.         unsigned size = length;
  127.         while (size && (size & 1) == 0) size >>= 1;
  128.         if (size & ~1)
  129.         {
  130.             if (!silentident)
  131.                 printf("NOT A ROM\n");
  132.         }
  133.         else
  134.         {
  135.             if (!silentident)
  136.                 printf("NO MATCH\n");
  137.             if (knownstatus == KNOWN_START)
  138.                 knownstatus = KNOWN_NONE;
  139.             else if (knownstatus == KNOWN_ALL)
  140.                 knownstatus = KNOWN_SOME;
  141.         }
  142.     }
  143.     else
  144.     {
  145.         if (knownstatus == KNOWN_START)
  146.             knownstatus = KNOWN_ALL;
  147.         else if (knownstatus == KNOWN_NONE)
  148.             knownstatus = KNOWN_SOME;
  149.     }
  150. #else
  151. /* New output format */
  152.     int i;
  153.     printf("%s\n",name);
  154.  
  155.     for (i = 0; drivers[i]; i++) {
  156.         const struct RomModule *romp;
  157.  
  158.         romp = drivers[i]->rom;
  159.  
  160.         while (romp && (romp->name || romp->offset || romp->length))
  161.         {
  162.             if (romp->name && romp->name != (char *)-1 && checksum == romp->crc)
  163.             {
  164.                 printf("\t%s/%s %s, %s, %s\n",drivers[i]->name,romp->name,
  165.                     drivers[i]->description,
  166.                     drivers[i]->manufacturer,
  167.                     drivers[i]->year);
  168.             }
  169.             romp++;
  170.         }
  171.     }
  172. #endif
  173. }
  174.  
  175. /* Identifies a file from from this checksum */
  176. void identify_file(const char* name)
  177. {
  178.     FILE *f;
  179.     int length;
  180.     char* data;
  181.  
  182.     f = fopen(name,"rb");
  183.     if (!f) {
  184.         return;
  185.     }
  186.  
  187.     /* determine length of file */
  188.     if (fseek (f, 0L, SEEK_END)!=0)    {
  189.         fclose(f);
  190.         return;
  191.     }
  192.  
  193.     length = ftell(f);
  194.     if (length == -1L) {
  195.         fclose(f);
  196.         return;
  197.     }
  198.  
  199.     /* empty file */
  200.     if (!length) {
  201.         fclose(f);
  202.         return;
  203.     }
  204.  
  205.     /* allocate space for entire file */
  206.     data = (char*)malloc(length);
  207.     if (!data) {
  208.         fclose(f);
  209.         return;
  210.     }
  211.  
  212.     if (fseek (f, 0L, SEEK_SET)!=0) {
  213.         free(data);
  214.         fclose(f);
  215.         return;
  216.     }
  217.  
  218.     if (fread(data, 1, length, f) != length) {
  219.         free(data);
  220.         fclose(f);
  221.         return;
  222.     }
  223.  
  224.     fclose(f);
  225.  
  226.     identify_rom(name, crc32(0L,(const unsigned char*)data,length),length);
  227.  
  228.     free(data);
  229. }
  230.  
  231. void identify_zip(const char* zipname)
  232. {
  233.     struct zipent* ent;
  234.  
  235.     ZIP* zip = openzip( zipname );
  236.     if (!zip)
  237.         return;
  238.  
  239.     while ((ent = readzip(zip))) {
  240.         /* Skip empty file and directory */
  241.         if (ent->uncompressed_size!=0) {
  242.             char* buf = (char*)malloc(strlen(zipname)+1+strlen(ent->name)+1);
  243.             sprintf(buf,"%s/%s",zipname,ent->name);
  244.             identify_rom(buf,ent->crc32,ent->uncompressed_size);
  245.             free(buf);
  246.         }
  247.     }
  248.  
  249.     closezip(zip);
  250. }
  251.  
  252. void romident(const char* name, int enter_dirs);
  253.  
  254. void identify_dir(const char* dirname)
  255. {
  256.     DIR *dir;
  257.     struct dirent *ent;
  258.  
  259.     dir = opendir(dirname);
  260.     if (!dir) {
  261.         return;
  262.     }
  263.  
  264.     ent = readdir(dir);
  265.     while (ent) {
  266.         /* Skip special files */
  267.         if (ent->d_name[0]!='.') {
  268.             char* buf = (char*)malloc(strlen(dirname)+1+strlen(ent->d_name)+1);
  269.             sprintf(buf,"%s/%s",dirname,ent->d_name);
  270.             romident(buf,0);
  271.             free(buf);
  272.         }
  273.  
  274.         ent = readdir(dir);
  275.     }
  276.     closedir(dir);
  277. }
  278.  
  279. void romident(const char* name,int enter_dirs) {
  280.     struct stat s;
  281.  
  282.     if (stat(name,&s) != 0)    {
  283.         printf("%s: %s\n",name,strerror(errno));
  284.         return;
  285.     }
  286.  
  287.     if (S_ISDIR(s.st_mode)) {
  288.         if (enter_dirs)
  289.             identify_dir(name);
  290.     } else {
  291.         unsigned l = strlen(name);
  292.         if (l>=4 && stricmp(name+l-4,".zip")==0)
  293.             identify_zip(name);
  294.         else
  295.             identify_file(name);
  296.         return;
  297.     }
  298. }
  299.  
  300.  
  301. #ifndef MESS
  302. enum { LIST_LIST = 1, LIST_LISTINFO, LIST_LISTFULL, LIST_LISTSAMDIR, LIST_LISTROMS, LIST_LISTSAMPLES,
  303.         LIST_LMR, LIST_LISTDETAILS, LIST_GAMELISTHEADER, LIST_GAMELISTFOOTER, LIST_GAMELIST,
  304.         LIST_LISTGAMES, LIST_LISTCLONES,
  305.         LIST_WRONGORIENTATION, LIST_WRONGFPS, LIST_LISTCRC, LIST_LISTDUPCRC, LIST_WRONGMERGE,
  306.         LIST_LISTROMSIZE, LIST_LISTCPU, LIST_SOURCEFILE };
  307. #else
  308. enum { LIST_LIST = 1, LIST_LISTINFO, LIST_LISTFULL, LIST_LISTSAMDIR, LIST_LISTROMS, LIST_LISTSAMPLES,
  309.         LIST_LMR, LIST_LISTDETAILS, LIST_GAMELISTHEADER, LIST_GAMELISTFOOTER, LIST_GAMELIST,
  310.         LIST_LISTGAMES, LIST_LISTCLONES,
  311.         LIST_WRONGORIENTATION, LIST_WRONGFPS, LIST_LISTCRC, LIST_LISTDUPCRC, LIST_WRONGMERGE,
  312.         LIST_LISTROMSIZE, LIST_LISTCPU, LIST_SOURCEFILE, LIST_MESSINFO };
  313. #endif
  314.  
  315.  
  316. #define VERIFY_ROMS        0x00000001
  317. #define VERIFY_SAMPLES    0x00000002
  318. #define VERIFY_VERBOSE    0x00000004
  319. #define VERIFY_TERSE    0x00000008
  320.  
  321. void CLIB_DECL terse_printf(char *fmt,...)
  322. {
  323.     /* no-op */
  324. }
  325.  
  326.  
  327. int frontend_help (int argc, char **argv)
  328. {
  329.     int i, j;
  330.     int list = 0;
  331.     int listclones = 1;
  332.     int verify = 0;
  333.     int ident = 0;
  334.     int help = 1;    /* by default is TRUE */
  335.     char gamename[9];
  336.  
  337.     /* covert '/' in '-' */
  338.     for (i = 1;i < argc;i++) if (argv[i][0] == '/') argv[i][0] = '-';
  339.  
  340.     /* by default display the help unless */
  341.     /* a game or an utility are specified */
  342.  
  343.     strcpy(gamename, "");
  344.  
  345.     for (i = 1;i < argc;i++)
  346.     {
  347.         /* find the FIRST "gamename" field (without '-') */
  348.         if ((strlen(gamename) == 0) && (argv[i][0] != '-'))
  349.         {
  350.             /* check if a filename was entered as the game name */
  351.             /* and remove any remaining portion of file extension */
  352.             for (j = 0;j < 8 && argv[i][j] && argv[i][j] != '.';j++)
  353.                 gamename[j] = argv[i][j];
  354.             gamename[j] = 0;
  355.         }
  356.     }
  357.  
  358.     for (i = 1; i < argc; i++)
  359.     {
  360.         /* check for front-end utilities */
  361.         if (!stricmp(argv[i],"-list")) list = LIST_LIST;
  362.          if (!stricmp(argv[i],"-listinfo")) list = LIST_LISTINFO;
  363.         if (!stricmp(argv[i],"-listfull")) list = LIST_LISTFULL;
  364.         if (!stricmp(argv[i],"-listdetails")) list = LIST_LISTDETAILS; /* A detailed MAMELIST.TXT type roms lister */
  365.         if (!stricmp(argv[i],"-gamelistheader")) list = LIST_GAMELISTHEADER; /* GAMELIST.TXT */
  366.         if (!stricmp(argv[i],"-gamelistfooter")) list = LIST_GAMELISTFOOTER; /* GAMELIST.TXT */
  367.         if (!stricmp(argv[i],"-gamelist")) list = LIST_GAMELIST; /* GAMELIST.TXT */
  368.         if (!stricmp(argv[i],"-listgames")) list = LIST_LISTGAMES;
  369.         if (!stricmp(argv[i],"-listclones")) list = LIST_LISTCLONES;
  370.         if (!stricmp(argv[i],"-listsamdir")) list = LIST_LISTSAMDIR;
  371.         if (!stricmp(argv[i],"-listcrc")) list = LIST_LISTCRC;
  372.         if (!stricmp(argv[i],"-listdupcrc")) list = LIST_LISTDUPCRC;
  373.         if (!stricmp(argv[i],"-listwrongmerge")) list = LIST_WRONGMERGE;
  374.         if (!stricmp(argv[i],"-listromsize")) list = LIST_LISTROMSIZE;
  375.         if (!stricmp(argv[i],"-listcpu")) list = LIST_LISTCPU;
  376.  
  377. #ifdef MAME_DEBUG /* do not put this into a public release! */
  378.         if (!stricmp(argv[i],"-lmr")) list = LIST_LMR;
  379. #endif
  380.         if (!stricmp(argv[i],"-wrongorientation")) list = LIST_WRONGORIENTATION;
  381.         if (!stricmp(argv[i],"-wrongfps")) list = LIST_WRONGFPS;
  382.         if (!stricmp(argv[i],"-noclones")) listclones = 0;
  383.         #ifdef MESS
  384.                 if (!stricmp(argv[i],"-listdevices"))  list = LIST_MESSINFO;
  385.                 if (!stricmp(argv[i],"-listtext")) list = LIST_MESSINFO;
  386.         #endif
  387.  
  388.  
  389.         /* these options REQUIRES gamename field to work */
  390.         if (strlen(gamename) > 0)
  391.         {
  392.             if (!stricmp(argv[i],"-listroms")) list = LIST_LISTROMS;
  393.             if (!stricmp(argv[i],"-listsamples")) list = LIST_LISTSAMPLES;
  394.             if (!stricmp(argv[i],"-verifyroms")) verify = VERIFY_ROMS;
  395.             if (!stricmp(argv[i],"-verifysets")) verify = VERIFY_ROMS|VERIFY_VERBOSE|VERIFY_TERSE;
  396.             if (!stricmp(argv[i],"-vset")) verify = VERIFY_ROMS|VERIFY_VERBOSE;
  397.             if (!stricmp(argv[i],"-verifysamples")) verify = VERIFY_SAMPLES|VERIFY_VERBOSE;
  398.             if (!stricmp(argv[i],"-vsam")) verify = VERIFY_SAMPLES|VERIFY_VERBOSE;
  399.             if (!stricmp(argv[i],"-romident")) ident = 1;
  400.             if (!stricmp(argv[i],"-isknown")) ident = 2;
  401.             if (!stricmp(argv[i],"-sourcefile")) list = LIST_SOURCEFILE;
  402.         }
  403.     }
  404.  
  405.     if ((strlen(gamename)> 0) || list || verify) help = 0;
  406.  
  407.     for (i = 1;i < argc;i++)
  408.     {
  409.         /* ...however, I WANT the help! */
  410.         if (!stricmp(argv[i],"-?") || !stricmp(argv[i],"-h") || !stricmp(argv[i],"-help"))
  411.             help = 1;
  412.     }
  413.  
  414.     if (help)  /* brief help - useful to get current version info */
  415.     {
  416.         #ifndef MESS
  417.         printf("M.A.M.E. v%s - Multiple Arcade Machine Emulator\n"
  418.                 "Copyright (C) 1997-2000 by Nicola Salmoria and the MAME Team\n\n",build_version);
  419.         showdisclaimer();
  420.         printf("Usage:  MAME gamename [options]\n\n"
  421.                 "        MAME -list      for a brief list of supported games\n"
  422.                 "        MAME -listfull  for a full list of supported games\n\n"
  423.                 "See readme.txt for a complete list of options.\n");
  424.         #else
  425.         showmessinfo();
  426.         #endif
  427.         return 0;
  428.     }
  429.  
  430.     switch (list)  /* front-end utilities ;) */
  431.     {
  432.  
  433.         #ifdef MESS
  434.         case LIST_MESSINFO: /* all mess specific calls here */
  435.         {
  436.             for (i=1;i<argc;i++)
  437.             {
  438.                 /* list all mess info options here */
  439.                 if (
  440.                     !stricmp(argv[i],"-listdevices") |
  441.                     !stricmp(argv[i],"-listtext")
  442.                    )
  443.                  {
  444.                     /* send the gamename and arg to mess.c */
  445.                     list_mess_info(gamename, argv[i], listclones);
  446.                 }
  447.             }
  448.             return 0;
  449.             break;
  450.         }
  451.         #endif
  452.  
  453.         case LIST_LIST: /* simple games list */
  454.             #ifndef MESS
  455.             printf("\nMAME currently supports the following games:\n\n");
  456.             #else
  457.             printf("\nMESS currently supports the following systems:\n\n");
  458.             #endif
  459.             i = 0; j = 0;
  460.             while (drivers[i])
  461.             {
  462.                 if ((listclones || drivers[i]->clone_of == 0
  463.                         || (drivers[i]->clone_of->flags & NOT_A_DRIVER)
  464.                         ) && !strwildcmp(gamename, drivers[i]->name))
  465.                 {
  466.                     printf("%-8s",drivers[i]->name);
  467.                     j++;
  468.                     if (!(j % 8)) printf("\n");
  469.                     else printf("  ");
  470.                 }
  471.                 i++;
  472.             }
  473.             if (j % 8) printf("\n");
  474.             printf("\n");
  475.             if (j != i) printf("Total ROM sets displayed: %4d - ", j);
  476.             #ifndef MESS
  477.             printf("Total ROM sets supported: %4d\n", i);
  478.             #else
  479.             printf("Total Systems supported: %4d\n", i);
  480.             #endif
  481.             return 0;
  482.             break;
  483.  
  484.         case LIST_LISTFULL: /* games list with descriptions */
  485.             printf("Name:     Description:\n");
  486.             i = 0;
  487.             while (drivers[i])
  488.             {
  489.                 if ((listclones || drivers[i]->clone_of == 0
  490.                         || (drivers[i]->clone_of->flags & NOT_A_DRIVER)
  491.                         ) && !strwildcmp(gamename, drivers[i]->name))
  492.                 {
  493.                     char name[200];
  494.  
  495.                     printf("%-10s",drivers[i]->name);
  496.  
  497.                     strcpy(name,drivers[i]->description);
  498.  
  499.                     /* Move leading "The" to the end */
  500.                     if (strstr(name," (")) *strstr(name," (") = 0;
  501.                     if (strncmp(name,"The ",4) == 0)
  502.                     {
  503.                         printf("\"%s",name+4);
  504.                         printf(", The");
  505.                     }
  506.                     else
  507.                         printf("\"%s",name);
  508.  
  509.                     /* print the additional description only if we are listing clones */
  510.                     if (listclones)
  511.                     {
  512.                         if (strchr(drivers[i]->description,'('))
  513.                             printf(" %s",strchr(drivers[i]->description,'('));
  514.                     }
  515.                     printf("\"\n");
  516.                 }
  517.                 i++;
  518.             }
  519.             return 0;
  520.             break;
  521.  
  522.         case LIST_LISTSAMDIR: /* games list with samples directories */
  523.             printf("Name:     Samples dir:\n");
  524.             i = 0;
  525.             while (drivers[i])
  526.             {
  527.                 if ((listclones || drivers[i]->clone_of == 0
  528.                         || (drivers[i]->clone_of->flags & NOT_A_DRIVER)
  529.                         ) && !strwildcmp(gamename, drivers[i]->name))
  530.                 {
  531. #if (HAS_SAMPLES)
  532.                     for( j = 0; drivers[i]->drv->sound[j].sound_type && j < MAX_SOUND; j++ )
  533.                     {
  534.                         const char **samplenames;
  535.                         if( drivers[i]->drv->sound[j].sound_type != SOUND_SAMPLES )
  536.                             continue;
  537.                         samplenames = ((struct Samplesinterface *)drivers[i]->drv->sound[j].sound_interface)->samplenames;
  538.                         if (samplenames != 0 && samplenames[0] != 0)
  539.                         {
  540.                             printf("%-10s",drivers[i]->name);
  541.                             if (samplenames[0][0] == '*')
  542.                                 printf("%s\n",samplenames[0]+1);
  543.                             else
  544.                                 printf("%s\n",drivers[i]->name);
  545.                         }
  546.                     }
  547. #endif
  548.                 }
  549.                 i++;
  550.             }
  551.             return 0;
  552.             break;
  553.  
  554.         case LIST_LISTROMS: /* game roms list or */
  555.         case LIST_LISTSAMPLES: /* game samples list */
  556.             j = 0;
  557.             while (drivers[j] && (stricmp(gamename,drivers[j]->name) != 0))
  558.                 j++;
  559.             if (drivers[j] == 0)
  560.             {
  561.                 printf("Game \"%s\" not supported!\n",gamename);
  562.                 return 1;
  563.             }
  564.             gamedrv = drivers[j];
  565.             if (list == LIST_LISTROMS)
  566.                 printromlist(gamedrv->rom,gamename);
  567.             else
  568.             {
  569. #if (HAS_SAMPLES)
  570.                 int k;
  571.                 for( k = 0; gamedrv->drv->sound[k].sound_type && k < MAX_SOUND; k++ )
  572.                 {
  573.                     const char **samplenames;
  574.                     if( gamedrv->drv->sound[k].sound_type != SOUND_SAMPLES )
  575.                         continue;
  576.                     samplenames = ((struct Samplesinterface *)gamedrv->drv->sound[k].sound_interface)->samplenames;
  577.                     if (samplenames != 0 && samplenames[0] != 0)
  578.                     {
  579.                         i = 0;
  580.                         while (samplenames[i] != 0)
  581.                         {
  582.                             printf("%s\n",samplenames[i]);
  583.                             i++;
  584.                         }
  585.                     }
  586.                 }
  587. #endif
  588.             }
  589.             return 0;
  590.             break;
  591.  
  592.         case LIST_LMR:
  593.             {
  594.                 int total;
  595.  
  596.                 total = 0;
  597.                 for (i = 0; drivers[i]; i++)
  598.                         total++;
  599.                 for (i = 0; drivers[i]; i++)
  600.                 {
  601.                     static int first_missing = 1;
  602.                     get_rom_sample_path (argc, argv, i);
  603.                     if (RomsetMissing (i))
  604.                     {
  605.                         if (first_missing)
  606.                         {
  607.                             first_missing = 0;
  608.                             printf ("game      clone of  description\n");
  609.                             printf ("--------  --------  -----------\n");
  610.                         }
  611.                         printf ("%-10s%-10s%s\n",
  612.                                 drivers[i]->name,
  613.                                 (drivers[i]->clone_of) ? drivers[i]->clone_of->name : "",
  614.                                 drivers[i]->description);
  615.                     }
  616.                     fprintf(stderr,"%d%%\r",100 * (i+1) / total);
  617.                 }
  618.             }
  619.             return 0;
  620.             break;
  621.  
  622.         case LIST_LISTDETAILS: /* A detailed MAMELIST.TXT type roms lister */
  623.  
  624.             /* First, we shall print the header */
  625.  
  626.             printf(" romname driver     ");
  627.             for(j=0;j<MAX_CPU;j++) printf("cpu %d    ",j+1);
  628.             for(j=0;j<MAX_SOUND;j++) printf("sound %d     ",j+1);
  629.             printf("name\n");
  630.             printf("-------- ---------- ");
  631.             for(j=0;j<MAX_CPU;j++) printf("-------- ");
  632.             for(j=0;j<MAX_SOUND;j++) printf("----------- ");
  633.             printf("--------------------------\n");
  634.  
  635.             /* Let's cycle through the drivers */
  636.  
  637.             i = 0;
  638.  
  639.             while (drivers[i])
  640.             {
  641.                 if ((listclones || drivers[i]->clone_of == 0
  642.                         || (drivers[i]->clone_of->flags & NOT_A_DRIVER)
  643.                         ) && !strwildcmp(gamename, drivers[i]->name))
  644.                 {
  645.                     /* Dummy structs to fetch the information from */
  646.  
  647.                     const struct MachineDriver *x_driver = drivers[i]->drv;
  648.                     const struct MachineCPU *x_cpu = x_driver->cpu;
  649.                     const struct MachineSound *x_sound = x_driver->sound;
  650.  
  651.                     /* First, the rom name */
  652.  
  653.                     printf("%-8s ",drivers[i]->name);
  654.  
  655.                     #ifndef MESS
  656.                     /* source file (skip the leading "src/drivers/" */
  657.                     printf("%-10s ",&drivers[i]->source_file[12]);
  658.                     #else
  659.                     /* source file (skip the leading "src/mess/systems/" */
  660.                     printf("%-10s ",&drivers[i]->source_file[17]);
  661.                     #endif
  662.  
  663.                     /* Then, cpus */
  664.  
  665.                     for(j=0;j<MAX_CPU;j++)
  666.                     {
  667.                         if (x_cpu[j].cpu_type & CPU_AUDIO_CPU)
  668.                             printf("[%-6s] ",cputype_name(x_cpu[j].cpu_type));
  669.                         else
  670.                             printf("%-8s ",cputype_name(x_cpu[j].cpu_type));
  671.                     }
  672.  
  673.                     /* Then, sound chips */
  674.  
  675.                     for(j=0;j<MAX_SOUND;j++)
  676.                     {
  677.                         if (sound_num(&x_sound[j]))
  678.                         {
  679.                             printf("%dx",sound_num(&x_sound[j]));
  680.                             printf("%-9s ",sound_name(&x_sound[j]));
  681.                         }
  682.                         else
  683.                             printf("%-11s ",sound_name(&x_sound[j]));
  684.                     }
  685.  
  686.                     /* Lastly, the name of the game and a \newline */
  687.  
  688.                     printf("%s\n",drivers[i]->description);
  689.                 }
  690.                 i++;
  691.             }
  692.             return 0;
  693.             break;
  694.  
  695.         case LIST_GAMELISTHEADER: /* GAMELIST.TXT */
  696.             printf("This is the complete list of games supported by MAME %s\n",build_version);
  697.             if (!listclones)
  698.                 printf("Variants of the same game are not included, you can use the -listclones command\n"
  699.                     "to get a list of the alternate versions of a given game.\n");
  700.             printf("\n"
  701.                 "The list is generated automatically and is not 100%% accurate, particularly in\n"
  702.                 "the \"Screen Flip\" column. Please let us know of any errors you find so we can\n"
  703.                 "correct them.\n"
  704.                 "\n"
  705.                 "The meanings of the columns are as follows:\n"
  706.                 "Working - \"No\" means that the emulation has shortcomings that cause the game\n"
  707.                 "  not to work correctly. This can be anywhere from just showing a black screen\n"
  708.                 "  to being playable with major problems.\n"
  709.                 "Correct Colors - \"Yes\" means that colors should be identical to the original,\n"
  710.                 "  \"Close\" that they are very similar but wrong in places, \"No\" that they are\n"
  711.                 "  completely wrong. In some cases, we were not able to find the color PROMs of\n"
  712.                 "  the game. Those PROMs will be reported as \"NO GOOD DUMP KNOWN\" on startup,\n"
  713.                 "  and the game will have wrong colors. The game is still reported as \"Yes\" in\n"
  714.                 "  this column, because the code to handle the color PROMs is in the driver and\n"
  715.                 "  if you provide them colors will be correct.\n"
  716.                 "Sound - \"Partial\" means that sound support is either incomplete or not entirely\n"
  717.                 "  accurate. Note that, due to analog circuitry which is difficult to emulate,\n"
  718.                 "  sound may be significantly different from the real board. A common case is\n"
  719.                 "  the presence of low pass filters that make the real board sound less harsh\n"
  720.                 "  than the emulation.\n"
  721.                 "Screen Flip - A large number of games have a dip switch setting for \"Cocktail\"\n"
  722.                 "  cabinet, meaning that the players sit in front of each other, and the screen\n"
  723.                 "  is flipped when player 2 is playing. Some games also have a \"Flip Screen\" dip\n"
  724.                 "  switch. Those need special support in the driver, which is missing in many\n"
  725.                 "  cases.\n"
  726.                 "Internal Name - This is the unique name that should be specified on the command\n"
  727.                 "  line to run the game. ROMs must be placed in the ROM path, either in a .zip\n"
  728.                 "  file or in a subdirectory of the same name. The former is suggested, because\n"
  729.                 "  the files will be identified by their CRC instead of requiring specific\n"
  730.                 "  names.\n\n");
  731.             printf("+----------------------------------+-------+-------+-------+-------+----------+\n");
  732.             printf("|                                  |       |Correct|       |Screen | Internal |\n");
  733.             printf("| Game Name                        |Working|Colors | Sound | Flip  |   Name   |\n");
  734.             printf("+----------------------------------+-------+-------+-------+-------+----------+\n");
  735.             return 0;
  736.             break;
  737.  
  738.         case LIST_GAMELISTFOOTER: /* GAMELIST.TXT */
  739.             printf("+----------------------------------+-------+-------+-------+-------+----------+\n\n");
  740.             printf("(1) There are variants of the game (usually bootlegs) that work correctly\n");
  741. #if (HAS_SAMPLES)
  742.             printf("(2) Needs samples provided separately\n");
  743. #endif
  744.             return 0;
  745.             break;
  746.  
  747.         case LIST_GAMELIST: /* GAMELIST.TXT */
  748.             i = 0;
  749.  
  750.             while (drivers[i])
  751.             {
  752.                 if ((listclones || drivers[i]->clone_of == 0
  753.                         || (drivers[i]->clone_of->flags & NOT_A_DRIVER)
  754.                         ) && !strwildcmp(gamename, drivers[i]->name))
  755.                 {
  756.                     char name[200],name_ref[200];
  757.  
  758.                     strcpy(name,drivers[i]->description);
  759.  
  760.                     /* Move leading "The" to the end */
  761.                     if (strstr(name," (")) *strstr(name," (") = 0;
  762.                     if (strncmp(name,"The ",4) == 0)
  763.                     {
  764.                         sprintf(name_ref,"%s, The ",name+4);
  765.                     }
  766.                     else
  767.                         sprintf(name_ref,"%s ",name);
  768.  
  769.                     /* print the additional description only if we are listing clones */
  770.                     if (listclones)
  771.                     {
  772.                         if (strchr(drivers[i]->description,'('))
  773.                             strcat(name_ref,strchr(drivers[i]->description,'('));
  774.                     }
  775.  
  776.                     printf("| %-33.33s",name_ref);
  777.  
  778.                     if (drivers[i]->flags & (GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION))
  779.                     {
  780.                         const struct GameDriver *maindrv;
  781.                         int foundworking;
  782.  
  783.                         if (drivers[i]->clone_of && !(drivers[i]->clone_of->flags & NOT_A_DRIVER))
  784.                             maindrv = drivers[i]->clone_of;
  785.                         else maindrv = drivers[i];
  786.  
  787.                         foundworking = 0;
  788.                         j = 0;
  789.                         while (drivers[j])
  790.                         {
  791.                             if (drivers[j] == maindrv || drivers[j]->clone_of == maindrv)
  792.                             {
  793.                                 if ((drivers[j]->flags & (GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION)) == 0)
  794.                                 {
  795.                                     foundworking = 1;
  796.                                     break;
  797.                                 }
  798.                             }
  799.                             j++;
  800.                         }
  801.  
  802.                         if (foundworking)
  803.                             printf("| No(1) ");
  804.                         else
  805.                             printf("|   No  ");
  806.                     }
  807.                     else
  808.                         printf("|  Yes  ");
  809.  
  810.                     if (drivers[i]->flags & GAME_WRONG_COLORS)
  811.                         printf("|   No  ");
  812.                     else if (drivers[i]->flags & GAME_IMPERFECT_COLORS)
  813.                         printf("| Close ");
  814.                     else
  815.                         printf("|  Yes  ");
  816.  
  817.                     {
  818.                         const char **samplenames = 0;
  819. #if (HAS_SAMPLES)
  820.                         for (j = 0;drivers[i]->drv->sound[j].sound_type && j < MAX_SOUND; j++)
  821.                         {
  822.                             if (drivers[i]->drv->sound[j].sound_type == SOUND_SAMPLES)
  823.                             {
  824.                                 samplenames = ((struct Samplesinterface *)drivers[i]->drv->sound[j].sound_interface)->samplenames;
  825.                                 break;
  826.                             }
  827.                         }
  828. #endif
  829.                         if (drivers[i]->flags & GAME_NO_SOUND)
  830.                             printf("|   No  ");
  831.                         else if (drivers[i]->flags & GAME_IMPERFECT_SOUND)
  832.                         {
  833.                             if (samplenames)
  834.                                 printf("|Part(2)");
  835.                             else
  836.                                 printf("|Partial");
  837.                         }
  838.                         else
  839.                         {
  840.                             if (samplenames)
  841.                                 printf("| Yes(2)");
  842.                             else
  843.                                 printf("|  Yes  ");
  844.                         }
  845.                     }
  846.  
  847.                     if (drivers[i]->flags & GAME_NO_COCKTAIL)
  848.                         printf("|   No  ");
  849.                     else
  850.                         printf("|  Yes  ");
  851.  
  852.                     printf("| %-8s |\n",drivers[i]->name);
  853.                 }
  854.                 i++;
  855.             }
  856.             return 0;
  857.             break;
  858.  
  859.         case LIST_LISTGAMES: /* list games, production year, manufacturer */
  860.             i = 0;
  861.             while (drivers[i])
  862.             {
  863.                 if ((listclones || drivers[i]->clone_of == 0
  864.                         || (drivers[i]->clone_of->flags & NOT_A_DRIVER)
  865.                         ) && !strwildcmp(gamename, drivers[i]->description))
  866.                 {
  867.                     char name[200];
  868.  
  869.                     printf("%-5s%-36s ",drivers[i]->year,drivers[i]->manufacturer);
  870.  
  871.                     strcpy(name,drivers[i]->description);
  872.  
  873.                     /* Move leading "The" to the end */
  874.                     if (strstr(name," (")) *strstr(name," (") = 0;
  875.                     if (strncmp(name,"The ",4) == 0)
  876.                     {
  877.                         printf("%s",name+4);
  878.                         printf(", The");
  879.                     }
  880.                     else
  881.                         printf("%s",name);
  882.  
  883.                     /* print the additional description only if we are listing clones */
  884.                     if (listclones)
  885.                     {
  886.                         if (strchr(drivers[i]->description,'('))
  887.                             printf(" %s",strchr(drivers[i]->description,'('));
  888.                     }
  889.                     printf("\n");
  890.                 }
  891.                 i++;
  892.             }
  893.             return 0;
  894.             break;
  895.  
  896.         case LIST_LISTCLONES: /* list clones */
  897.             printf("Name:    Clone of:\n");
  898.             i = 0;
  899.             while (drivers[i])
  900.             {
  901.                 if (drivers[i]->clone_of && !(drivers[i]->clone_of->flags & NOT_A_DRIVER) &&
  902.                         (!strwildcmp(gamename,drivers[i]->name)
  903.                                 || !strwildcmp(gamename,drivers[i]->clone_of->name)))
  904.                     printf("%-8s %-8s\n",drivers[i]->name,drivers[i]->clone_of->name);
  905.                 i++;
  906.             }
  907.             return 0;
  908.             break;
  909.  
  910.         case LIST_WRONGORIENTATION: /* list drivers which incorrectly use the orientation and visible area fields */
  911.             while (drivers[i])
  912.             {
  913.                 if ((drivers[i]->drv->video_attributes & VIDEO_TYPE_VECTOR) == 0 &&
  914.                         (drivers[i]->clone_of == 0
  915.                                 || (drivers[i]->clone_of->flags & NOT_A_DRIVER)) &&
  916.                         drivers[i]->drv->visible_area.max_x - drivers[i]->drv->visible_area.min_x + 1 <=
  917.                         drivers[i]->drv->visible_area.max_y - drivers[i]->drv->visible_area.min_y + 1)
  918.                 {
  919.                     if (strcmp(drivers[i]->name,"crater") &&
  920.                         strcmp(drivers[i]->name,"mpatrol") &&
  921.                         strcmp(drivers[i]->name,"troangel") &&
  922.                         strcmp(drivers[i]->name,"travrusa") &&
  923.                         strcmp(drivers[i]->name,"kungfum") &&
  924.                         strcmp(drivers[i]->name,"battroad") &&
  925.                         strcmp(drivers[i]->name,"vigilant") &&
  926.                         strcmp(drivers[i]->name,"sonson") &&
  927.                         strcmp(drivers[i]->name,"brkthru") &&
  928.                         strcmp(drivers[i]->name,"darwin") &&
  929.                         strcmp(drivers[i]->name,"exprraid") &&
  930.                         strcmp(drivers[i]->name,"sidetrac") &&
  931.                         strcmp(drivers[i]->name,"targ") &&
  932.                         strcmp(drivers[i]->name,"spectar") &&
  933.                         strcmp(drivers[i]->name,"venture") &&
  934.                         strcmp(drivers[i]->name,"mtrap") &&
  935.                         strcmp(drivers[i]->name,"pepper2") &&
  936.                         strcmp(drivers[i]->name,"hardhat") &&
  937.                         strcmp(drivers[i]->name,"fax") &&
  938.                         strcmp(drivers[i]->name,"circus") &&
  939.                         strcmp(drivers[i]->name,"robotbwl") &&
  940.                         strcmp(drivers[i]->name,"crash") &&
  941.                         strcmp(drivers[i]->name,"ripcord") &&
  942.                         strcmp(drivers[i]->name,"starfire") &&
  943.                         strcmp(drivers[i]->name,"fireone") &&
  944.                         strcmp(drivers[i]->name,"renegade") &&
  945.                         strcmp(drivers[i]->name,"battlane") &&
  946.                         strcmp(drivers[i]->name,"megatack") &&
  947.                         strcmp(drivers[i]->name,"killcom") &&
  948.                         strcmp(drivers[i]->name,"challeng") &&
  949.                         strcmp(drivers[i]->name,"kaos") &&
  950.                         strcmp(drivers[i]->name,"formatz") &&
  951.                         strcmp(drivers[i]->name,"bankp") &&
  952.                         strcmp(drivers[i]->name,"liberatr") &&
  953.                         strcmp(drivers[i]->name,"toki") &&
  954.                         strcmp(drivers[i]->name,"stactics") &&
  955.                         strcmp(drivers[i]->name,"sprint1") &&
  956.                         strcmp(drivers[i]->name,"sprint2") &&
  957.                         strcmp(drivers[i]->name,"nitedrvr") &&
  958.                         strcmp(drivers[i]->name,"punchout") &&
  959.                         strcmp(drivers[i]->name,"spnchout") &&
  960.                         strcmp(drivers[i]->name,"armwrest") &&
  961.                         strcmp(drivers[i]->name,"route16") &&
  962.                         strcmp(drivers[i]->name,"stratvox") &&
  963.                         strcmp(drivers[i]->name,"irobot") &&
  964.                         strcmp(drivers[i]->name,"leprechn") &&
  965.                         strcmp(drivers[i]->name,"starcrus") &&
  966.                         strcmp(drivers[i]->name,"astrof") &&
  967.                         strcmp(drivers[i]->name,"tomahawk") &&
  968.                         1)
  969.                         printf("%s %dx%d\n",drivers[i]->name,
  970.                                 drivers[i]->drv->visible_area.max_x - drivers[i]->drv->visible_area.min_x + 1,
  971.                                 drivers[i]->drv->visible_area.max_y - drivers[i]->drv->visible_area.min_y + 1);
  972.                 }
  973.                 i++;
  974.             }
  975.             return 0;
  976.             break;
  977.  
  978.         case LIST_WRONGFPS: /* list drivers with too high frame rate */
  979.             while (drivers[i])
  980.             {
  981.                 if ((drivers[i]->drv->video_attributes & VIDEO_TYPE_VECTOR) == 0 &&
  982.                         (drivers[i]->clone_of == 0
  983.                                 || (drivers[i]->clone_of->flags & NOT_A_DRIVER)) &&
  984.                         drivers[i]->drv->frames_per_second > 57 &&
  985.                         drivers[i]->drv->visible_area.max_y - drivers[i]->drv->visible_area.min_y + 1 > 244 &&
  986.                         drivers[i]->drv->visible_area.max_y - drivers[i]->drv->visible_area.min_y + 1 <= 256)
  987.                 {
  988.                     printf("%s %dx%d %fHz\n",drivers[i]->name,
  989.                             drivers[i]->drv->visible_area.max_x - drivers[i]->drv->visible_area.min_x + 1,
  990.                             drivers[i]->drv->visible_area.max_y - drivers[i]->drv->visible_area.min_y + 1,
  991.                             drivers[i]->drv->frames_per_second);
  992.                 }
  993.                 i++;
  994.             }
  995.             return 0;
  996.             break;
  997.  
  998.         case LIST_SOURCEFILE:
  999.             i = 0;
  1000.             while (drivers[i])
  1001.             {
  1002.                 if (!strwildcmp(gamename,drivers[i]->name))
  1003.                     printf("%-8s %s\n",drivers[i]->name,drivers[i]->source_file);
  1004.                 i++;
  1005.             }
  1006.             return 0;
  1007.             break;
  1008.  
  1009.         case LIST_LISTCRC: /* list all crc-32 */
  1010.             i = 0;
  1011.             while (drivers[i])
  1012.             {
  1013.                 const struct RomModule *romp;
  1014.  
  1015.                 romp = drivers[i]->rom;
  1016.  
  1017.                 while (romp && (romp->name || romp->offset || romp->length))
  1018.                 {
  1019.                     if (romp->name && romp->name != (char *)-1)
  1020.                         printf("%08x %-12s %s\n",romp->crc,romp->name,drivers[i]->description);
  1021.  
  1022.                     romp++;
  1023.                 }
  1024.  
  1025.                 i++;
  1026.             }
  1027.             return 0;
  1028.             break;
  1029.  
  1030.         case LIST_LISTDUPCRC: /* list duplicate crc-32 (with different ROM name) */
  1031.             i = 0;
  1032.             while (drivers[i])
  1033.             {
  1034.                 const struct RomModule *romp;
  1035.  
  1036.                 romp = drivers[i]->rom;
  1037.  
  1038.                 while (romp && (romp->name || romp->offset || romp->length))
  1039.                 {
  1040.                     if (romp->name && romp->name != (char *)-1 && romp->crc)
  1041.                     {
  1042.                         j = i+1;
  1043.                         while (drivers[j])
  1044.                         {
  1045.                             const struct RomModule *romp1;
  1046.  
  1047.                             romp1 = drivers[j]->rom;
  1048.  
  1049.                             while (romp1 && (romp1->name || romp1->offset || romp1->length))
  1050.                             {
  1051.                                 if (romp1->name && romp1->name != (char *)-1 &&
  1052.                                         strcmp(romp->name,romp1->name) &&
  1053.                                         romp1->crc == romp->crc)
  1054.                                 {
  1055.                                     printf("%08x %-12s %-8s <-> %-12s %-8s\n",romp->crc,
  1056.                                             romp->name,drivers[i]->name,
  1057.                                             romp1->name,drivers[j]->name);
  1058.                                 }
  1059.  
  1060.                                 romp1++;
  1061.                             }
  1062.  
  1063.                             j++;
  1064.                         }
  1065.                     }
  1066.  
  1067.                     romp++;
  1068.                 }
  1069.  
  1070.                 i++;
  1071.             }
  1072.             return 0;
  1073.             break;
  1074.  
  1075.  
  1076.         case LIST_WRONGMERGE: /* list duplicate crc-32 with different ROM name in clone sets */
  1077.             i = 0;
  1078.             while (drivers[i])
  1079.             {
  1080.                 const struct RomModule *romp;
  1081.  
  1082.                 romp = drivers[i]->rom;
  1083.  
  1084.                 while (romp && (romp->name || romp->offset || romp->length))
  1085.                 {
  1086.                     if (romp->name && romp->name != (char *)-1 && romp->crc)
  1087.                     {
  1088.                         j = 0;
  1089.                         while (drivers[j])
  1090.                         {
  1091.                             if (j != i &&
  1092.                                 drivers[j]->clone_of &&
  1093.                                 (drivers[j]->clone_of->flags & NOT_A_DRIVER) == 0 &&
  1094.                                 (drivers[j]->clone_of == drivers[i] ||
  1095.                                 (i < j && drivers[j]->clone_of == drivers[i]->clone_of)))
  1096.                             {
  1097.                                 const struct RomModule *romp1;
  1098.                                 int match;
  1099.  
  1100.  
  1101.                                 romp1 = drivers[j]->rom;
  1102.                                 match = 0;
  1103.  
  1104.                                 while (romp1 && (romp1->name || romp1->offset || romp1->length))
  1105.                                 {
  1106.                                     if (romp1->name && romp1->name != (char *)-1 &&
  1107.                                             !strcmp(romp->name,romp1->name))
  1108.                                     {
  1109.                                         match = 1;
  1110.                                         break;
  1111.                                     }
  1112.  
  1113.                                     romp1++;
  1114.                                 }
  1115.  
  1116.                                 if (match == 0)
  1117.                                 {
  1118.                                     romp1 = drivers[j]->rom;
  1119.  
  1120.                                     while (romp1 && (romp1->name || romp1->offset || romp1->length))
  1121.                                     {
  1122.                                         if (romp1->name && romp1->name != (char *)-1 &&
  1123.                                                 strcmp(romp->name,romp1->name) &&
  1124.                                                 romp1->crc == romp->crc)
  1125.                                         {
  1126.                                             printf("%08x %-12s %-8s <-> %-12s %-8s\n",romp->crc,
  1127.                                                     romp->name,drivers[i]->name,
  1128.                                                     romp1->name,drivers[j]->name);
  1129.                                         }
  1130.  
  1131.                                         romp1++;
  1132.                                     }
  1133.                                 }
  1134.                             }
  1135.                             j++;
  1136.                         }
  1137.                     }
  1138.  
  1139.                     romp++;
  1140.                 }
  1141.  
  1142.                 i++;
  1143.             }
  1144.             return 0;
  1145.             break;
  1146.  
  1147.         case LIST_LISTROMSIZE: /* I used this for statistical analysis */
  1148.             i = 0;
  1149.             while (drivers[i])
  1150.             {
  1151.                 if (drivers[i]->clone_of == 0 || (drivers[i]->clone_of->flags & NOT_A_DRIVER))
  1152.                 {
  1153.                     const struct RomModule *romp;
  1154.                     j = 0;
  1155.  
  1156.                     romp = drivers[i]->rom;
  1157.  
  1158.                     while (romp && (romp->name || romp->offset || romp->length))
  1159.                     {
  1160.                         j += romp->length & ~ROMFLAG_MASK;
  1161.  
  1162.                         romp++;
  1163.                     }
  1164.                     printf("%-8s\t%-5s\t%u\n",drivers[i]->name,drivers[i]->year,j);
  1165.                 }
  1166.  
  1167.                 i++;
  1168.             }
  1169.             return 0;
  1170.             break;
  1171.  
  1172.         case LIST_LISTCPU: /* I used this for statistical analysis */
  1173.             {
  1174.                 int year;
  1175.  
  1176.                 for (j = 1;j < CPU_COUNT;j++)
  1177.                     printf("\t%s",cputype_name(j));
  1178.                 printf("\n");
  1179.  
  1180.                 for (year = 1980;year <= 1995;year++)
  1181.                 {
  1182.                     int count[CPU_COUNT];
  1183.  
  1184.                     for (j = 0;j < CPU_COUNT;j++)
  1185.                         count[j] = 0;
  1186.  
  1187.                     i = 0;
  1188.                     while (drivers[i])
  1189.                     {
  1190.                         if (drivers[i]->clone_of == 0 || (drivers[i]->clone_of->flags & NOT_A_DRIVER))
  1191.                         {
  1192.                             const struct MachineDriver *x_driver = drivers[i]->drv;
  1193.                             const struct MachineCPU *x_cpu = x_driver->cpu;
  1194.  
  1195.                             if (atoi(drivers[i]->year) == year)
  1196.                             {
  1197. //                                for (j = 0;j < MAX_CPU;j++)
  1198. j = 0;    // count only the main cpu
  1199.                                     count[x_cpu[j].cpu_type & ~CPU_FLAGS_MASK]++;
  1200.                             }
  1201.                         }
  1202.  
  1203.                         i++;
  1204.                     }
  1205.  
  1206.                     printf("%d",year);
  1207.                     for (j = 1;j < CPU_COUNT;j++)
  1208.                         printf("\t%d",count[j]);
  1209.                     printf("\n");
  1210.                 }
  1211.             }
  1212.  
  1213.             return 0;
  1214.             break;
  1215.  
  1216.         case LIST_LISTINFO: /* list all info */
  1217.             print_mame_info( stdout, drivers );
  1218.             return 0;
  1219.     }
  1220.  
  1221.     if (verify)  /* "verify" utilities */
  1222.     {
  1223.         int err = 0;
  1224.         int correct = 0;
  1225.         int incorrect = 0;
  1226.         int res = 0;
  1227.         int total = 0;
  1228.         int checked = 0;
  1229.         int notfound = 0;
  1230.  
  1231.  
  1232.         for (i = 0; drivers[i]; i++)
  1233.         {
  1234.             if (!strwildcmp(gamename, drivers[i]->name))
  1235.                 total++;
  1236.         }
  1237.  
  1238.         for (i = 0; drivers[i]; i++)
  1239.         {
  1240.             if (strwildcmp(gamename, drivers[i]->name))
  1241.                 continue;
  1242.  
  1243.             /* set rom and sample path correctly */
  1244.             get_rom_sample_path (argc, argv, i);
  1245.  
  1246.             if (verify & VERIFY_ROMS)
  1247.             {
  1248.                 res = VerifyRomSet (i,(verify & VERIFY_TERSE) ? terse_printf : (verify_printf_proc)printf);
  1249.  
  1250.                 if (res == CLONE_NOTFOUND || res == NOTFOUND)
  1251.                 {
  1252.                     notfound++;
  1253.                     goto nextloop;
  1254.                 }
  1255.  
  1256.                 if (res == INCORRECT || res == BEST_AVAILABLE || (verify & VERIFY_VERBOSE))
  1257.                 {
  1258.                     printf ("romset %s ", drivers[i]->name);
  1259.                     if (drivers[i]->clone_of && !(drivers[i]->clone_of->flags & NOT_A_DRIVER))
  1260.                         printf ("[%s] ", drivers[i]->clone_of->name);
  1261.                 }
  1262.             }
  1263.             if (verify & VERIFY_SAMPLES)
  1264.             {
  1265.                 const char **samplenames = NULL;
  1266. #if (HAS_SAMPLES)
  1267.                 for( j = 0; drivers[i]->drv->sound[j].sound_type && j < MAX_SOUND; j++ )
  1268.                     if( drivers[i]->drv->sound[j].sound_type == SOUND_SAMPLES )
  1269.                         samplenames = ((struct Samplesinterface *)drivers[i]->drv->sound[j].sound_interface)->samplenames;
  1270. #endif
  1271.                 /* ignore games that need no samples */
  1272.                 if (samplenames == 0 || samplenames[0] == 0)
  1273.                     goto nextloop;
  1274.  
  1275.                 res = VerifySampleSet (i,(verify_printf_proc)printf);
  1276.                 if (res == NOTFOUND)
  1277.                 {
  1278.                     notfound++;
  1279.                     goto nextloop;
  1280.                 }
  1281.                 printf ("sampleset %s ", drivers[i]->name);
  1282.             }
  1283.  
  1284.             if (res == NOTFOUND)
  1285.             {
  1286.                 printf ("oops, should never come along here\n");
  1287.             }
  1288.             else if (res == INCORRECT)
  1289.             {
  1290.                 printf ("is bad\n");
  1291.                 incorrect++;
  1292.             }
  1293.             else if (res == CORRECT)
  1294.             {
  1295.                 if (verify & VERIFY_VERBOSE)
  1296.                     printf ("is good\n");
  1297.                 correct++;
  1298.             }
  1299.             else if (res == BEST_AVAILABLE)
  1300.             {
  1301.                 printf ("is best available\n");
  1302.                 correct++;
  1303.             }
  1304.             if (res)
  1305.                 err = res;
  1306.  
  1307. nextloop:
  1308.             checked++;
  1309.             fprintf(stderr,"%d%%\r",100 * checked / total);
  1310.         }
  1311.  
  1312.         if (correct+incorrect == 0)
  1313.         {
  1314.             printf ("%s ", (verify & VERIFY_ROMS) ? "romset" : "sampleset" );
  1315.             if (notfound > 0)
  1316.                 printf("\"%8s\" not found!\n",gamename);
  1317.             else
  1318.                 printf("\"%8s\" not supported!\n",gamename);
  1319.             return 1;
  1320.         }
  1321.         else
  1322.         {
  1323.             printf("%d %s found, %d were OK.\n", correct+incorrect,
  1324.                     (verify & VERIFY_ROMS)? "romsets" : "samplesets", correct);
  1325.             if (incorrect > 0)
  1326.                 return 2;
  1327.             else
  1328.                 return 0;
  1329.         }
  1330.     }
  1331.     if (ident)
  1332.     {
  1333.         if (ident == 2) silentident = 1;
  1334.         else silentident = 0;
  1335.  
  1336.         for (i = 1;i < argc;i++)
  1337.         {
  1338.             /* find the FIRST "name" field (without '-') */
  1339.             if (argv[i][0] != '-')
  1340.             {
  1341.                 knownstatus = KNOWN_START;
  1342.                 romident(argv[i],1);
  1343.                 if (ident == 2)
  1344.                 {
  1345.                     switch (knownstatus)
  1346.                     {
  1347.                         case KNOWN_START: printf("ERROR     %s\n",argv[i]); break;
  1348.                         case KNOWN_ALL:   printf("KNOWN     %s\n",argv[i]); break;
  1349.                         case KNOWN_NONE:  printf("UNKNOWN   %s\n",argv[i]); break;
  1350.                         case KNOWN_SOME:  printf("PARTKNOWN %s\n",argv[i]); break;
  1351.                     }
  1352.                 }
  1353.                 break;
  1354.             }
  1355.         }
  1356.         return 0;
  1357.     }
  1358.  
  1359.     /* use a special return value if no frontend function used */
  1360.  
  1361.     return 1234;
  1362. }
  1363.